/*
 * Created on 10.03.2006
 *
 */
package visiopuce.ideogram;

import java.awt.Color;
import java.io.Serializable;

import javax.swing.event.ChangeListener;

import visiopuce.ideogram.event.IChangeNotifier;
import visiopuce.ideogram.input.FileVersion;
import visiopuce.ideogram.util.ChangeNotifier;
import visiopuce.ideogram.util.SystemUtility;

/**
 *  
 * @author muellera
 *
 */
public class AllParameters implements Serializable, IChangeNotifier, Cloneable
{
    private static final long serialVersionUID = 3L;
    
    // default values for lower and upper bounds
    // V1.0 defaults
    private static final float LOG2RATIO_LOW 		=  -1.0f;
    private static final float LOG2RATIO_UP  		=   1.0f;
    private static final float GSA_LOW 				=   1.0f;
    private static final float GSA_UP  				=   3.0f;
    private static final float SPA_LOW 				=   1.0f;
    private static final float SPA_UP  				=   3.0f;
    private static final float LOH_UP 				=  10.0f;  
    // V1.1 defauls
    private static final float LOG2RATIO_LOW_NEW	=  -0.4f;
    private static final float LOG2RATIO_UP_NEW 	=   0.4f;
    private static final float HMMLOG2RATIO_LOW 	= -0.25f;
    private static final float HMMLOG2RATIO_UP  	=  0.25f;
    private static final float NEGLOG10PVALUE_LOW	=   0.0f;
    private static final float NEGLOG10PVALUE_UP 	=   3.0f;
	private static final float LOHPROB_UP 			=  0.25f;
	//
    private static final float MINLENGTH			= 	0.0f;
    private static final int   GROUPLIM				=      3;
    private static final int   CONSENSUSTHRESH		=      1;

    // default color values
	private static final Color COL_DLOSS 	= new Color(255, 0, 0);
	private static final Color COL_LOSS		= new Color(255, 136, 245);
	private static final Color COL_GAIN		= new Color(103, 193, 244);
	private static final Color COL_AMP		= new Color(0, 0, 255);
	private static final Color COL_MOZ		= new Color(51, 153, 153);
	private static final Color COL_LCSH		= new Color(96, 54, 138);
    
    private transient ChangeNotifier	notifier;

    // global parameters
    public enum Method { NORMAL, RELIABILITY };
    
    // Fields for Version 1.0
    public enum FieldA {
    	LOGRATIO, GSA, SPA,  LOH;		// unused: CALL
    }
    
    // Fields for Version 1.1
    public enum FieldB {
    	LOGRATIO, HMMMEDIANLOG2RATIO, NEGLOG10PVALUE,
    	CNSTATE,  LOHPROB, 
    	};
    /* unused 1.1 fields:
    	HMMMEDIANLOG2RATIOMIN, HMMMEDIANLOG2RATIOMAX,
    	CNSTATEMIN, CNSTATEMAX, NEGLOG10PVALUEMIN,
    	NEGLOG10PVALUEMAX, LOG2RATIOMIN, LOG2RATIOMAX,
    	CALL */
    	
    public FieldA		fieldA;			// selected value for 1.0 file format combobox
    public FieldB		fieldB;			// selected value for 1.1 file format combobox
    public float        log2ratio_lower,
						log2ratio_upper,
						log2ratio_lower_new,
						log2ratio_upper_new,
						gsa_lower,
						gsa_upper,
						spa_lower,
						spa_upper,
						loh_upper,
						min_length,
    					hmmlog2ratio_lower,
    					hmmlog2ratio_upper, 
    					neglog10pvalue_lower,
    					neglog10pvalue_upper,
    					lohprob_upper;

    public int			group_lim;
	public boolean 		consensus_mode;
	public int	 		consensus_threshold;
		
	public Method 		method;			// filtering configuration
	public boolean 		preFilter, 
						postFilter;

	
	public FileVersion	versionLoaded;
	
	public Color		doublelossColor, lossColor, gainColor, ampColor, lcshColor, mozColor;
	
	public boolean 		invertColors;
	
    /**
     * default constructor
     */
    public AllParameters()
    {
    	restoreDefaultColors();
    	fieldA = FieldA.LOGRATIO;
    	fieldB = FieldB.CNSTATE;
    	log2ratio_lower=LOG2RATIO_LOW;
		log2ratio_upper=LOG2RATIO_UP;
		gsa_lower=GSA_LOW;
		gsa_upper=GSA_UP;
		spa_lower=SPA_LOW;
		spa_upper=SPA_UP;
		loh_upper=LOH_UP;
		min_length=MINLENGTH;
		
		// new for 1.1 file format
		log2ratio_lower_new = LOG2RATIO_LOW_NEW;
		log2ratio_upper_new = LOG2RATIO_UP_NEW;
		hmmlog2ratio_lower = HMMLOG2RATIO_LOW;
		hmmlog2ratio_upper = HMMLOG2RATIO_UP;
		neglog10pvalue_lower = NEGLOG10PVALUE_LOW;
		neglog10pvalue_upper = NEGLOG10PVALUE_UP;
		lohprob_upper = LOHPROB_UP;
		
		group_lim=GROUPLIM;
		
		consensus_threshold =CONSENSUSTHRESH;
		consensus_mode = false;
		
		method = Method.NORMAL;
		preFilter = true;
		postFilter = false;
	
				
		invertColors = false;
		
		versionLoaded = FileVersion.UNKNOWN;
		
		initTransientState();
    }
    
    protected void initTransientState()
    {
		notifier = new ChangeNotifier();    	
    }

  

    public Object clone()
    {
        return SystemUtility.serialClone(this);
    }
    
    @SuppressWarnings("ucd")
    protected void fireChangeEvent()
    {
    	notifier.fireChangeEvent();
    }
    
	public void addChangeListener( ChangeListener listener )
	{
		notifier.addChangeListener( listener );
	}

	public void removeChangeListener(ChangeListener listener)
	{
		notifier.removeChangeListener( listener );
	}
	
	/**
	 * 
	 * @return Bounds depending on the selected field #field.
	 */
	public float[] getBounds() {
		float[] bounds = new float[2];
		if (versionLoaded == FileVersion.V1_0) {
			switch (fieldA) {
			case LOGRATIO:
				bounds[0] = log2ratio_lower;
				bounds[1] = log2ratio_upper;
				break;
			case LOH:
				bounds[0] = Float.NEGATIVE_INFINITY;
				bounds[1] = loh_upper;
				break;
			case GSA:
				bounds[0] = gsa_lower;
				bounds[1] = gsa_upper;
				break;
			case SPA:
				bounds[0] = spa_lower;
				bounds[1] = spa_upper;
				break;
			default:
				throw new IllegalStateException("illegal field selected");
			}
		} else {
			switch (fieldB) {
			case CNSTATE:
				bounds[0] = 0.0f;
				bounds[1] = 0.0f;
				break;
		
			case LOGRATIO:
				bounds[0] = log2ratio_lower_new;
				bounds[1] = log2ratio_upper_new;
				break;

			case HMMMEDIANLOG2RATIO:
				bounds[0] = hmmlog2ratio_lower;
				bounds[1] = hmmlog2ratio_upper;
				break;

			case NEGLOG10PVALUE:
				bounds[0] = neglog10pvalue_lower;
				bounds[1] = neglog10pvalue_upper;
				break;

			case LOHPROB:
				bounds[0] = 0.0f;
				bounds[1] = lohprob_upper;
				break;

			default:
				throw new IllegalStateException("illegal field selected");
			}
		}

		return bounds;
	}

	public FieldA getFieldA()
	{
		return fieldA;
	}
	
	public FieldB getFieldB() {
		return fieldB;
	}

	public void setField(FieldA field )
	{
		this.fieldA = field;
	}
	
	public void setField(FieldB field) {
		this.fieldB = field;
	}

	public String getFieldName()
	{
		if(versionLoaded==FileVersion.V1_0)	return getFieldName(fieldA);
		else return getFieldName(fieldB);
	}

	static public String getFieldName(FieldA field)
	{
		return field.toString();
	}
	
	static public String getFieldName(FieldB field)
	{
		return field.toString();
	}	



	public void setInvertColors(boolean invertColors) {
		if(this.invertColors!=invertColors) {
			this.invertColors = invertColors;
			Color temp;
			temp = doublelossColor;
			doublelossColor = ampColor;
			ampColor = temp;
			temp = lossColor;
			lossColor = gainColor;
			gainColor = temp;
		}
	}

	public Color getColor(int cn, boolean marker_state) {
		Color c;
		switch (cn) {
		case 0:
			c = doublelossColor;
			break;
		case 1:
			c = lossColor;
			break;
		case 3:
			c = gainColor;
			break;
		case 4:
			c = ampColor;
			break;
		case -100:
			c = lcshColor;
			break;
		case -1000:
			c = mozColor;
			break;
		default:
			c = null;
		}
		if (c != null) {
			if (marker_state) {
				c = c.brighter();
			}
		}
		return c;
	}
	

	
	public FileVersion getVersionLoaded() {
		return versionLoaded;
	}

	public void setVersionLoaded(FileVersion versionLoaded) {
		this.versionLoaded = versionLoaded;
	}

	public void restoreDefaultColors() {
    	doublelossColor = COL_DLOSS;
    	lossColor = COL_LOSS;
    	gainColor = COL_GAIN;
    	ampColor = COL_AMP;
    	mozColor = COL_MOZ;
    	lcshColor = COL_LCSH;
	}

	public String getOptions() {
		String s = "";
		if(getFieldName().equals("LOGRATIO")) {
			if(versionLoaded == FileVersion.V1_1)
				s=s+ "lower: "+log2ratio_lower_new+" upper: "+log2ratio_upper_new;
			else s=s+  "lower: "+log2ratio_lower+" upper: "+log2ratio_upper;
		}
		if(getFieldName().equals("HMMMEDIANLOG2RATIO")) s=s+"lower: "+hmmlog2ratio_lower+" upper: "+hmmlog2ratio_upper;
		if(getFieldName().equals("NEGLOG10PVALUE")) s=s+"lower: "+neglog10pvalue_lower+" upper: "+neglog10pvalue_upper;
		if(getFieldName().equals("LOHPROB")) s=s+"upper: "+lohprob_upper;
		if(getFieldName().equals("LOH")) s=s+"upper: "+loh_upper;		
		if(getFieldName().equals("GSA")) s=s+"lower: "+gsa_lower+" upper: "+gsa_upper;
		if(getFieldName().equals("SPA")) s=s+"lower: "+spa_lower+" upper: "+spa_upper;
		
		s = s + " group limit: "+group_lim+" min length: "+min_length; 
		return s;
	}

}

